# -*- coding: utf-8 -*-
# @Time: 2025/5/23 16:54
# @Author: wzd
# @Email: 2146333089@qq.com
# @File: view1.py
import uuid

import bcrypt
from django.http import JsonResponse
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_exempt
from django.contrib.auth.hashers import make_password, check_password
from django.db.models import Q
from .models import Admin, Student, Teacher, School
from .jwt_utils import generate_jwt_token, decode_jwt_token, jwt_required
from .serializers import AdminSerializer, StudentSerializer, TeacherSerializer


@csrf_exempt
@require_http_methods(["POST"])
def multi_field_login(request):
    """多字段登录视图，支持用户名/学号/教师号、邮箱、手机号登录"""
    """    
    - 学生用学号登录时必须提供学校
    - 学生用邮箱/手机登录时无需学校
    """
    try:
        data = json.loads(request.body.decode("utf-8"))
        login_id = data.get('login_id')
        password = data.get('password')
        user_type = data.get('user_type')
        school_id = data.get('school_id')  # 可选参数

        # 基础参数验证
        if not all([login_id, password, user_type]):
            return JsonResponse({
                'code': 400,
                'message': '缺少login_id、password或user_type参数'
            }, status=400)

        # 定义用户模型映射
        user_model_mapping = {
            'admin': Admin,
            'student': Student,
            'teacher': Teacher
        }
        UserModel = user_model_mapping.get(user_type)
        if not UserModel:
            return JsonResponse({
                'code': 400,
                'message': '无效的用户类型，支持：admin/student/teacher'
            }, status=400)

        # 构建查询条件
        query = Q()

        if user_type in ['student', 'teacher']:
            # 学生教师登录逻辑
            if '@' in login_id or (login_id.isdigit() and len(login_id) == 11):
                # 邮箱或手机登录（全局唯一，无需学校）
                query |= Q(email=login_id) if '@' in login_id else Q(phone=login_id)
            else:
                # 学号登录，必须提供学校
                if not school_id:
                    return JsonResponse({
                        'code': 400,
                        'message': '学生/教师用学号/工号登录时必须提供school_id'
                    }, status=400)

                # 验证学校存在
                if not School.objects.filter(school_id=school_id).exists():
                    return JsonResponse({
                        'code': 404,
                        'message': '学校不存在'
                    }, status=404)

                # 学号+学校组合查询
                if user_type == 'student':
                    query = Q(student_id=login_id) & Q(school_id=school_id)
                else:
                    query = Q(teacher_id=login_id) & Q(school_id=school_id)
        else:
            # 管理员登录逻辑
            if user_type == 'admin':
                query |= Q(name=login_id)

        # 执行查询
        try:
            user = UserModel.objects.get(query)
        except UserModel.DoesNotExist:
            return JsonResponse({
                'code': 401,
                'message': '用户不存在'
            }, status=401)

        # 密码验证
        if not check_password(password, user.password):
            return JsonResponse({
                'code': 401,
                'message': '密码错误'
            }, status=401)

        # 生成JWT Token（包含学校信息）
        school_id = user.school.school_id if hasattr(user, 'school') and user.school else None
        token = generate_jwt_token(user.id, user_type, school_id)

        # 构建用户信息响应
        user_info = {
            'id': user.id,
            'name': getattr(user, 'name', user.name),
            'user_type': user_type
        }
        if school_id:
            user_info['school'] = {
                'id': school_id,
                'name': user.school.name
            }

        return JsonResponse({
            'code': 200,
            'message': '登录成功',
            'token': token,
            'user_info': user_info
        })

    except json.JSONDecodeError:
        return JsonResponse({
            'code': 400,
            'message': '无效的JSON格式'
        }, status=400)
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'服务器错误: {str(e)}'
        }, status=500)


@jwt_required
@require_http_methods(["POST"])
def logout(request):
    """退出登录（JWT无法主动失效，客户端需自行删除Token）"""
    return JsonResponse({'code': 200, 'message': '退出成功'})
import json

@csrf_exempt
@require_http_methods(["POST"])
def register(request):
    """用户注册接口"""
    try:
        data = json.loads(request.body.decode("utf-8"))
        user_type = data.get('user_type')

        if user_type == 'admin':
            print(data)
            data['name'] = data.pop("username")
            print(data)
            serializer = AdminSerializer(data=data)
        elif user_type == 'student':
            serializer = StudentSerializer(data=data)
        elif user_type == 'teacher':
            print(data)
            serializer = TeacherSerializer(data=data)
        else:
            return JsonResponse({'code': 400, 'message': '无效的用户类型'}, status=400)
        if not serializer.is_valid():
            return JsonResponse({'code': 400, 'message': '参数错误', 'errors': serializer.errors}, status=400)
        validated_data = serializer.validated_data
        print(validated_data)
        password = validated_data.pop('password')
        if user_type == 'admin':
            user = Admin.objects.create(
                name=validated_data['name'],
                email=validated_data['email'],
                phone=validated_data.get('phone'),
                password=make_password(password)
            )
        elif user_type == 'student':
            school = School.objects.get(school_id=validated_data['school_id'])
            user = Student.objects.create(
                student_id=validated_data['student_id'],
                name=validated_data.get('name'),
                email=validated_data['email'],
                grade=validated_data.get('grade'),
                major=validated_data.get('major'),
                phone=validated_data.get('phone'),
                school=school,
                password=make_password(password)
            )
        elif user_type == 'teacher':
            school = School.objects.get(school_id=validated_data['school']['school_id'])
            user = Teacher.objects.create(
                teacher_id=validated_data['teacher_id'],
                name=validated_data.get('name'),
                email=validated_data['email'],
                title=validated_data.get('title'),
                department=validated_data.get('department'),
                phone=validated_data.get('phone'),
                school=school,
                password=make_password(password)
            )

        return JsonResponse({
            'code': 201,
            'message': f'{user_type}注册成功',
            'user_id': user.id
        }, status=201)

    except Exception as e:
        return JsonResponse({'code': 500, 'message': f'注册失败: {str(e)}'}, status=500)



@csrf_exempt
@require_http_methods(["GET"])
@jwt_required  # JWT验证装饰器，确保请求包含有效Token
def get_user_info(request):
    """
    获取当前登录用户的详细信息
    依赖JWT Token中的用户ID和类型
    """
    try:
        # 从请求中获取Token（假设jwt_required已解析并存储在request中）
        token = request.META.get('HTTP_AUTHORIZATION', '').split(' ')[-1]
        payload = decode_jwt_token(token)  # 解码Token获取载荷

        user_id = payload.get('user_id')
        user_type = payload.get('user_type')

        if not user_id or not user_type:
            return JsonResponse({
                'code': 401,
                'message': 'Token解析失败，缺少必要信息'
            }, status=401)

        # 根据用户类型查询对应模型
        user = None
        if user_type == 'admin':
            user = Admin.objects.get(id=user_id)
            serializer = AdminSerializer(user)
        elif user_type == 'student':
            user = Student.objects.get(id=user_id)
            serializer = StudentSerializer(user)
        elif user_type == 'teacher':
            user = Teacher.objects.get(id=user_id)
            serializer = TeacherSerializer(user)
        else:
            return JsonResponse({
                'code': 400,
                'message': '无效的用户类型'
            }, status=400)
        # 查看学校信息

        # 构建响应数据
        response_data = {
            'code': 200,
            'message': '获取用户信息成功',
            'user_info': serializer.data
        }

        return JsonResponse(response_data)

    except Admin.DoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '管理员用户不存在'
        }, status=404)
    except Student.DoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '学生用户不存在'
        }, status=404)
    except Teacher.DoesNotExist:
        return JsonResponse({
            'code': 404,
            'message': '教师用户不存在'
        }, status=404)
    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'获取用户信息失败: {str(e)}'
        }, status=500)



@csrf_exempt
@require_http_methods(["PUT"])
@jwt_required  # JWT验证装饰器
def update_student_info(request):
    """更新当前登录学生的信息（仅允许更新自身信息）"""
    try:
        # 从请求头获取Token并解析
        auth_header = request.headers.get('Authorization', '')
        if not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': 401,
                'message': '未提供有效的认证令牌'
            }, status=401)

        token = auth_header.split(' ')[1]
        payload = decode_jwt_token(token)

        if not payload:
            return JsonResponse({
                'code': 401,
                'message': '无效的认证令牌'
            }, status=401)

        # 验证用户类型为学生
        user_type = payload.get('user_type')
        school_id = payload.get('school_id')
        if user_type != 'student':
            return JsonResponse({
                'code': 403,
                'message': '权限不足，非学生用户'
            }, status=403)

        user_id = payload.get('user_id')
        if not user_id:
            return JsonResponse({
                'code': 401,
                'message': 'Token中缺少用户ID'
            }, status=401)

        # 获取当前学生对象
        try:
            student = Student.objects.get(id=user_id)
        except Student.DoesNotExist:
            return JsonResponse({
                'code': 404,
                'message': '学生用户不存在'
            }, status=404)

        # 解析请求数据
        try:
            data = json.loads(request.body)
        except json.JSONDecodeError:
            return JsonResponse({
                'code': 400,
                'message': '无效的JSON格式'
            }, status=400)

        # 定义可更新字段（排除学号和学校）
        updatable_fields = ['name', 'password', 'email', 'grade', 'major', 'phone']
        update_data = {}

        # 检查并过滤可更新字段
        for field in updatable_fields:
            if field in data:
                update_data[field] = data[field]

        # 数据验证
        if 'email' in update_data:
            # 检查邮箱唯一性（排除自身）
            if Student.objects.exclude(id=user_id).filter(email=update_data['email']).exists():
                return JsonResponse({
                    'code': 400,
                    'message': '邮箱已被其他用户使用'
                }, status=400)

        if 'password' in update_data:
            # 密码哈希处理
            update_data['password'] = bcrypt.hashpw(
                update_data['password'].encode('utf-8'),
                bcrypt.gensalt()
            ).decode('utf-8')

        # 更新字段
        for field, value in update_data.items():
            # 处理空字符串转None（针对可选字段）
            if value == '' and field in ['grade', 'major', 'phone']:
                value = None
            setattr(student, field, value)

        # 保存更新
        student.save()

        # 生成新Token（包含更新后的信息）
        new_token = generate_jwt_token(user_id, user_type, school_id)

        return JsonResponse({
            'code': 200,
            'message': '学生信息更新成功',
            'data': {
                'student_id': student.student_id,
                'name': student.name,
                'email': student.email,
                'grade': student.grade,
                'major': student.major,
                'phone': student.phone,
                'school': student.school.name if student.school else None,
                'updated_at': student.updated_at.strftime('%Y-%m-%d %H:%M:%S')
            },
            'token': new_token  # 返回新Token
        }, status=200)

    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'更新失败: {str(e)}'
        }, status=500)


# accounts/views.py
@csrf_exempt
@require_http_methods(["PUT"])
@jwt_required  # JWT验证装饰器
def update_teacher_info(request):
    """更新当前登录教师的信息（仅允许更新自身信息）"""
    try:
        # 解析JWT Token
        auth_header = request.headers.get('Authorization', '')
        if not auth_header.startswith('Bearer '):
            return JsonResponse({
                'code': 401,
                'message': '未提供有效的认证令牌'
            }, status=401)

        token = auth_header.split(' ')[1]
        payload = decode_jwt_token(token)

        if not payload:
            return JsonResponse({
                'code': 401,
                'message': '无效的认证令牌'
            }, status=401)

        # 验证用户类型为教师
        user_type = payload.get('user_type')
        school_id = payload.get('school_id')
        if user_type != 'teacher':
            return JsonResponse({
                'code': 403,
                'message': '权限不足，非教师用户'
            }, status=403)

        user_id = payload.get('user_id')
        if not user_id:
            return JsonResponse({
                'code': 401,
                'message': 'Token中缺少用户ID'
            }, status=401)


        # 获取当前教师对象
        try:
            teacher = Teacher.objects.get(id=user_id)
        except Teacher.DoesNotExist:
            return JsonResponse({
                'code': 404,
                'message': '教师用户不存在'
            }, status=404)

        # 解析请求数据
        try:
            data = json.loads(request.body)
            if not data.get('title'):
                return JsonResponse({
                    'code': 401,
                    'message': '请填写职称'
                }, status=401)
            if not data.get('department'):
                return JsonResponse({
                    'code': 401,
                    'message': '请填写所在院系/部门'
                }, status=401)
            if not data.get('email'):
                return JsonResponse({
                    'code': 401,
                    'message': '请填写邮箱'
                }, status=401)
            if not data.get('phone'):
                return JsonResponse({
                    'code': 401,
                    'message': '请填写手机号'
                }, status=401)
            if not data.get('sex'):
                return JsonResponse({
                    'code': 401,
                    'message': '请选择性别'
                }, status=401)
        except json.JSONDecodeError:
            return JsonResponse({
                'code': 400,
                'message': '无效的JSON格式'
            }, status=400)

        # 定义可更新字段（排除教师工号和学校）
        updatable_fields = ['name', 'password', 'email', 'title', 'department', 'phone']
        update_data = {}

        # 检查并过滤可更新字段
        for field in updatable_fields:
            if field in data:
                update_data[field] = data[field]

        # 数据验证
        if 'email' in update_data:
            # 检查邮箱唯一性（排除自身）
            print(user_id)
            if Teacher.objects.filter(email=update_data['email']).exclude(id=user_id).exists():
                return JsonResponse({
                    'code': 400,
                    'message': '邮箱已被其他用户使用'
                }, status=400)

        if 'password' in update_data:
            # 密码哈希处理
            update_data['password'] = bcrypt.hashpw(
                update_data['password'].encode('utf-8'),
                bcrypt.gensalt()
            ).decode('utf-8')

        # 更新字段
        for field, value in update_data.items():
            setattr(teacher, field, value)

        # 保存更新
        teacher.save()

        # 生成新Token（包含更新后的信息）
        new_token = generate_jwt_token(user_id, user_type, school_id)

        return JsonResponse({
            'code': 200,
            'message': '教师信息更新成功',
            'data': {
                'teacher_id': teacher.teacher_id,
                'name': teacher.name,
                'email': teacher.email,
                'title': teacher.title,
                'department': teacher.department,
                'phone': teacher.phone,
                'school': teacher.school.name if teacher.school else None,
                'updated_at': teacher.updated_at.strftime('%Y-%m-%d %H:%M:%S')
            },
            'token': new_token  # 返回新Token
        }, status=200)

    except Exception as e:
        return JsonResponse({
            'code': 500,
            'message': f'更新失败: {str(e)}'
        }, status=500)